﻿// E-Book Copier
// Copyright (C) 2009 Chuan-Gen Fan
// 
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
// 
// Project: http://code.google.com/p/ebookcopier/
// Contact Author:
//    website: http://chuangen.name/
// e-mail/msn: chuangen@live.cn

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace EbookCopier
{
    /// <summary>
    /// 屏幕剪辑工具。CaptureScreen
    /// </summary>
    public partial class SetRectForm : Form
    {
        /// <summary>
        /// 初始化类 <see cref="SetRectForm"/> 的新实例。
        /// </summary>
        /// <param name="screen">The screen.</param>
        public SetRectForm(Screen screen)
        {
            InitializeComponent();

            this.SetStyle(ControlStyles.AllPaintingInWmPaint
            | ControlStyles.OptimizedDoubleBuffer
            | ControlStyles.ResizeRedraw
            | ControlStyles.UserPaint
            | ControlStyles.SupportsTransparentBackColor,true);

            this.Cursor = Cursors.Cross;

            this.SetScreen(screen);
        }
        bool isMouseDown = false;
        Rectangle selectedRect = Rectangle.Empty;
        /// <summary>
        /// 选中的区域。
        /// </summary>
        public Rectangle SelectedRect
        {
            get { return selectedRect; }
        }

        Point startPoint;
        void SetStartPoint(Point startPoint)
        {
            this.startPoint = startPoint;
            selectedRect = new Rectangle(startPoint, Size.Empty);
            this.Invalidate();
        }
        void SetEndPoint(Point endPoint)
        {
            selectedRect = new Rectangle(
                Math.Min(startPoint.X, endPoint.X),
                Math.Min(startPoint.Y, endPoint.Y),
                Math.Abs(endPoint.X - startPoint.X),
                Math.Abs(endPoint.Y - startPoint.Y)
                );
            this.Invalidate();
        }

        /// <summary>
        /// 引发 <see cref="E:System.Windows.Forms.Control.KeyDown"></see> 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.KeyEventArgs"></see>。</param>
        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)
            {
                this.DialogResult = DialogResult.Cancel;
            }
            base.OnKeyDown(e);
        }

        Bitmap backImage =null;
        /// <summary>
        /// 设置要显示到的屏幕。
        /// </summary>
        /// <param name="screen">The screen.</param>
        public void SetScreen(Screen screen)
        {
            Rectangle bounds = screen.Bounds;
            backImage = new Bitmap(bounds.Width, bounds.Height);
            Graphics g = Graphics.FromImage(backImage);
            g.CopyFromScreen(bounds.Location, new Point(0, 0), bounds.Size);
            g.Dispose();

            this.FormBorderStyle = FormBorderStyle.None;
            this.ShowInTaskbar = false;
            this.TopMost = true;
            this.Bounds = screen.Bounds;
        }

        /// <summary>
        /// 引发 <see cref="E:Paint"/> 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 <see cref="System.Windows.Forms.PaintEventArgs"/> 实例。</param>
        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            Pen borderPen = Pens.Black;

            Rectangle scrRect =new Rectangle(0, 0, this.Width, this.Height);
            g.DrawImageUnscaledAndClipped(backImage, scrRect);

            Color color = Color.FromArgb(180, Color.White);
            GraphicsPath path = new GraphicsPath( FillMode.Alternate );
            path.AddRectangle(scrRect);

            Rectangle shownRect = new Rectangle(selectedRect.X,selectedRect.Y,(int)(selectedRect.Width - borderPen.Width),(int)(selectedRect.Height - borderPen.Width));

            if (selectedRect.Width != 0 && selectedRect.Height!=0)
                path.AddRectangle(shownRect);
            g.FillPath(new SolidBrush(color), path);
            if (selectedRect.Width != 0 && selectedRect.Height != 0)
            {
                if (shownRect.Width > 0 && shownRect.Height > 0)
                    g.DrawRectangle(borderPen, shownRect);
                else
                    g.DrawLine(borderPen, new Point(shownRect.X, shownRect.Y), new Point(shownRect.Right, shownRect.Bottom));
            }

            base.OnPaint(e);
        }

        /// <summary>
        /// 引发 <see cref="E:System.Windows.Forms.Control.MouseDown"></see> 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.MouseEventArgs"></see>。</param>
        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                isMouseDown = true;
                SetStartPoint(e.Location);
                this.Invalidate();
            }
            base.OnMouseDown(e);
        }

        /// <summary>
        /// 引发 <see cref="E:System.Windows.Forms.Control.MouseUp"></see> 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.MouseEventArgs"></see>。</param>
        protected override void OnMouseUp(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                this.isMouseDown = false;
                SetEndPoint(e.Location);

                if (selectedRect.Width > 0 && selectedRect.Height > 0)
                {//区域有效
                    this.DialogResult = DialogResult.OK;
                }
                else
                {
                    this.DialogResult = DialogResult.Cancel;
                }
            }
            base.OnMouseUp(e);
        }
        /// <summary>
        /// 引发 <see cref="E:System.Windows.Forms.Control.MouseMove"></see> 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.MouseEventArgs"></see>。</param>
        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (isMouseDown)
            {
                SetEndPoint(e.Location);
            }
            base.OnMouseMove(e);
        }
    }
}